import { Directive, DirectiveBinding, nextTick } from 'vue';

const lazyLoadHandler = (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const lazyImage = entry.target as HTMLImageElement;
            const src = lazyImage.dataset.src!;
            lazyImage.src = src;
            lazyImage.onload = () => {
                lazyImage.removeAttribute('data-src');
                observer.unobserve(lazyImage);
            };
            lazyImage.onerror = () => {
                // 加载失败，设置透明图 + 背景色
                // lazyImage.src =
                //     ''; // 1x1透明图
                lazyImage.style.objectFit = 'contain';
                const hue = Math.floor(Math.random() * 360); // 色相：0 - 360
                const randomHsl = `hsl(${hue}, 60%, 70%)`;    // 控制饱和度和亮度
                lazyImage.style.backgroundColor = randomHsl;
                lazyImage.style.display = 'block';
                lazyImage.removeAttribute('data-src');
                observer.unobserve(lazyImage);
            };
        }
    });
};

const lazyLoadOptions: IntersectionObserverInit = {
    root: null,
    threshold: 0.5,
    rootMargin: '0px',
};
export const LazyDirective: Directive<HTMLImageElement> = {
    beforeMount(el: HTMLImageElement, binding: DirectiveBinding) {
        if (binding.value) {
            const defaultLoadingSrc: string = 'https://s1.aigei.com/src/img/gif/04/042233ab580e4eccbb907f88f5ecee24.gif?imageMogr2/auto-orient/thumbnail/!282x282r/gravity/Center/crop/282x282/quality/85/%7CimageView2/2/w/282&e=2051020800&token=P7S2Xpzfz11vAkASLTkfHN7Fw-oOZBecqeJaxypL:nzISfMBrxXELVV40UfZS9tBx36E=';
            const defaultErrorSrc: string = 'https://www.minitu.cn/wp-content/uploads/2021/03/wjt1-300x213.png';
            el.dataset.src = binding.value;
            el.dataset.loadingSrc = el.src || defaultLoadingSrc;
            el.dataset.errorSrc = defaultErrorSrc;
            el.src = el.dataset.loadingSrc;
            setTimeout(() => {
                const observer = new IntersectionObserver(lazyLoadHandler, lazyLoadOptions);
                observer.observe(el);
            }, 100)
        }
    },
};

export default LazyDirective;
